﻿#include <iostream>
#include "bSpline.h"
#include <fstream>
#include <cmath>
#include <eigen3/Eigen/Dense>
#include <nlohmann/json.hpp>
#include <vector>

using namespace std;
class FucntionE_1 : public Function
{
public:
	double operator()(const double x) const {
        return (sqrt(3.0 - pow(x, 2)) + sqrt(fabs(x))) * 2 / 3;
	}
    double diff(const double x) const {
		return 0;
	}
	double diff2(const double x) const {
		return 0;
	}
} functionE_1;

class FucntionE_2 : public Function
{
public:
    double operator()(const double x) const {
        return (-sqrt(3.0 - pow(x, 2)) + sqrt(fabs(x))) * 2 / 3;
    }
    double diff(const double x) const {
        return 0;
    }
    double diff2(const double x) const {
        return 0;
    }
} functionE_2;

int main() {
    std::ifstream jsonFile("./json/E.json");
    nlohmann::json j;
    jsonFile >> j;
    vector<int> n_values = j["n"];

    for (int j = 0; j < n_values.size(); ++j) {
        vector<double> pointX, pointY, knots1, values1, knots2, values2;
        int n_temp = n_values[j];
        int udex = (n_temp - 1) / 4;
        int vdex = (n_temp - 1) % 4;
        for (int i = 0, m = udex + (vdex > 0); i < m; ++i) {
            double x = sqrt(3) * i / m;
            pointX.push_back(x);
            pointY.push_back(functionE_2(x));
        }
        pointX.push_back(sqrt(3));
        pointY.push_back(sqrt(sqrt(3)) * 2 / 3);

        for (int i = 1, m = udex + (vdex > 1); i < m; ++i) {
            double x = sqrt(3) * (m - i) / m;
            pointX.push_back(x);
            pointY.push_back(functionE_1(x));
        }

        for (int i = 0, m = udex + (vdex > 2); i < m; ++i) {
            double x = -sqrt(3) * i / m;
            pointX.push_back(x);
            pointY.push_back(functionE_1(x));
        }
        pointX.push_back(-sqrt(3));
        pointY.push_back(sqrt(sqrt(3)) * 2 / 3);

        for (int i = 1, m = udex; i < m; ++i) {
            double x = -sqrt(3) * (m - i) / m;
            pointX.push_back(x);
            pointY.push_back(functionE_2(x));
        }
        pointX.push_back(0);
        pointY.push_back(functionE_2(0));

        
        double temp = 0;
        for (int i = 0; i < n_temp; ++i) {
            if (i > 0)  temp += sqrt((pointX[i] - pointX[i - 1]) * (pointX[i] - pointX[i - 1]) + (pointY[i] - pointY[i - 1]) * (pointY[i] - pointY[i - 1]));
            knots1.push_back(temp);
            knots2.push_back(temp);
            values1.push_back(pointX[i]);
            values2.push_back(pointY[i]);
        }

        Bform s1(functionE_1, knots1, values1, 3, 2);
        Bform s2(functionE_2, knots2, values2, 3, 2);

        ofstream f1;
        f1.open("./Data/N =" + to_string(n_temp) + "CubicBspline.txt");
        for (int i = 0; i < 2000; ++i) {
            f1 << s1.cubic(temp * i / 1999) << ' ' << s2.cubic(temp * i / 1999) << endl;
        }
        f1.close();
    }
}


